package modifyx

func NewPoolList() (obj *PoolList) {
	obj = &PoolList{
		versions: map[string]int{},
	}
	return
}

type PoolList struct {
	root *Pool

	// 版本信息,
	// 保证一个root对象唯一, 需要传递给新的对象
	// 记录已经更新到的版本号，用于与修正池中的版本号进行对比。
	// 如果当前对象的版本号低于修正池中的版本号，则更新当前的对象到最新的版本
	versions map[string]int
	//
	newestVersionCreator func() int
}

func (p *PoolList) SetRoot(pool *Pool) {
	p.root = pool
}

func (p *PoolList) SetHost(pool *Pool) {
	if p.root == nil {
		p.root = pool
	} else {
		p.root.Parent = pool
	}
}

func (p *PoolList) Dispose() {
	p.root = nil
	p.versions = nil
	p.newestVersionCreator = nil
}

func (p *PoolList) SetNewestVersionCreator(val func() int) {
	p.newestVersionCreator = val
}

func (p *PoolList) GetNewestVersion() int {
	if p.newestVersionCreator != nil {
		return p.newestVersionCreator()
	}

	return 0
}

func (p *PoolList) IsPropChanged(key string) bool {
	lastVersion := p.versions[key]
	if p.root == nil {
		return false
	}
	cur := p.root
	for {
		if cur.IsPropChanged(key, lastVersion) {
			return true
		}

		cur = cur.Parent
		if cur == nil {
			return false
		}
	}
}

func (p *PoolList) GetNewPropInt(key string, val int) (r int) {
	var last = p.GetNewPropFloat(key, float64(val))
	return int(last)
}

func (p *PoolList) GetNewPropFloat(key string, val float64) (r float64) {
	last := val
	var changed = false
	// 第一步，计算修正
	{
		cur := p.root
		for {
			arr, has := cur.ModifyList[key]
			if has && arr.Length() > 0 {
				for _, imodify := range arr.Slice() {
					modify := imodify.(IModify)
					if !modify.Valid() {
						continue
					}
					changed = true
					// 计算修正
					last = modify.Value(val).(float64)
				}
			}
			cur = cur.Parent
			if cur == nil {
				break
			}
		}
	}

	// 第二步，计算加成
	{
		cur := p.root
		for {
			arr, has := cur.BonusList[key]
			if has && arr.Length() > 0 {
				var lastBonus *Bonus
				for _, ibonus := range arr.Slice() {
					bonus := ibonus.(IBonus)
					if !bonus.Valid() {
						continue
					}
					if lastBonus == nil {
						lastBonus = NewBonus("")
					}
					changed = true
					lastBonus.Combine(bonus)
				}

				if changed {
					last = CalculateBonusFactor(float64(val), lastBonus, true, true, true)
				}
			}
			cur = cur.Parent
			if cur == nil {
				break
			}
		}
	}

	r = last
	if changed {
		p.versions[key] = p.GetNewestVersion()
	}
	return
}

func (p *PoolList) GetNewPropBool(key string, val bool) (r bool) {
	last := val
	var changed = false
	// 第一步，计算修正
	{
		cur := p.root
		for {
			arr, has := cur.ModifyList[key]
			if has && arr.Length() > 0 {
				for _, imodify := range arr.Slice() {
					modify := imodify.(IModify)
					if !modify.Valid() {
						continue
					}
					changed = true
					// 计算修正
					//switch modify.(type) {
					//}
				}
			}
			cur = cur.Parent
			if cur == nil {
				break
			}
		}
	}

	r = last
	if changed {
		p.versions[key] = p.GetNewestVersion()
	}
	return
}
